﻿using AJWPFAdmin.Core.ExtensionMethods;
using AJWPFAdmin.Core.Logger;
using AJWPFAdmin.Core.Models;
using AJWPFAdmin.Core.Models.EF.Tables;
using AJWPFAdmin.Core.Utils;
using AJWPFAdmin.Services.EF;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AJWPFAdmin.Services.AppointAPI.GoodsInfoQuery
{
    public class BeiJingCEMGoodsInfoQuery : GoodsInfoQueryBase
    {
        #region Models

        public class BeijingCEMWeighingRecordModel
        {
            /// <summary>
            /// 车牌号码
            /// </summary>
            public string carno { get; set; }

            /// <summary>
            /// 物料编号
            /// </summary>
            public string wlbh { get; set; }

            /// <summary>
            /// 物料名称
            /// </summary>
            public string wlmc { get; set; }

            /// <summary>
            /// 物料种类
            /// </summary>
            public string wlzl { get; set; }

            /// <summary>
            /// 毛重
            /// </summary>
            public decimal mz { get; set; }

            /// <summary>
            /// 皮重
            /// </summary>
            public decimal pz { get; set; }

            /// <summary>
            /// 净重
            /// </summary>
            public decimal jz { get; set; }

            /// <summary>
            /// 毛重时间
            /// </summary>
            public DateTime? cmsj { get; set; }

            /// <summary>
            /// 皮重时间
            /// </summary>
            public DateTime? qpsj { get; set; }

            /// <summary>
            /// 磅房
            /// </summary>
            public string bf { get; set; }

            /// <summary>
            /// 原料厂家
            /// </summary>
            public string ylcj { get; set; }
        }

        #endregion

        private AJLog4NetLogger _logger;

        private string _token;
        private DateTime _tokenExpireDate;

        private HttpClient _client;

        private string _api;

        public BeiJingCEMGoodsInfoQuery(AJConfigService cfgSvc, DefaultAppointAPI.APIConfig apiConfig, AJLog4NetLogger logger, GoodsInfoQueryTemplate name) : base(cfgSvc, apiConfig, name)
        {
            _logger = logger;
            _client = CommonUtil.CreateCommonHttpClient();
            _api = "/api/bjcjjc/ExternalService";
        }

        public override void FillGoodsInfo(ref Car carInfo, WeighingDataCache cacheData)
        {
            carInfo.Code = cacheData.TicketCode;
            carInfo.Sender = cacheData.Sender;
            carInfo.Receiver = cacheData.Receiver;

            carInfo.SendOrReceiveFlag = cacheData.SendOrReceiveFlag;

            if (carInfo.SendOrReceiveFlag == "收货")
            {
                carInfo.InGoodsName = cacheData.GoodsName;
                carInfo.InGoodsVolume = cacheData.GoodsWeight;
                carInfo.InGoodsType = cacheData.GoodsType;
            }
            else
            {
                carInfo.OutGoodsName = cacheData.GoodsName;
                carInfo.OutGoodsVolume = cacheData.GoodsWeight;
                carInfo.OutGoodsType = cacheData.GoodsType;
            }
        }

        public override async Task<WeighingDataCache> QueryAsync(CarInfoParams carInfoParams)
        {
            WeighingDataCache data = null;

            try
            {
                var now = DateTime.Now;

                if (string.IsNullOrWhiteSpace(_token) || now > _tokenExpireDate)
                {
                    var tokenRet = await PostAsync(_api, new JObject
                    {
                        {"TBM_ID",_apiConfig.ApiToken },
                        {"Type", "ToKen" }
                    });

                    if (!tokenRet.Success)
                    {
                        _logger.Error($"{_name} 获取Token失败:{tokenRet.Message}");
                        return data;
                    }

                    var tokenObj = tokenRet.Data as JObject;

                    _token = tokenObj["token"].ToString();
                    _tokenExpireDate = now.AddMinutes(50);
                }

                var queryRet = await PostAsync(_api, new JObject
                {
                    {"Type", carInfoParams.Passageway.Direction == Core.Enums.PassagewayDirection.进 
                    ? "stuffweighin" : "deliveryweighed" },/*类型:过磅信息*/ 
                    {"TBM_ToKen", _token},/*秘钥*/ 
                    {"Date", now.AddDays(-29).ToCommonDateString()},/*开始时间*/ 
                    {"EndDate", now.ToCommonDateString()},/*截止时间*/ 
                    {"CarCaption", carInfoParams.CarInfo.CarNo}/*材料车号*/
                });

                if (!queryRet.Success)
                {
                    _logger.Error($"{_name} 查询地磅物资失败:{queryRet.Message}");
                    return data;
                }

                var queryResObj = queryRet.Data as JObject;

                var setting = CommonUtil.DEFAULTJSONSERIALIZERSETTINGS;

                var array = CommonUtil.TryGetJSONObject<BeijingCEMWeighingRecordModel[]>(CommonUtil.AJSerializeObject(queryResObj["data"], setting), setting) ?? Array.Empty<BeijingCEMWeighingRecordModel>();

                if (array.Length == 0)
                {
                    _logger.Info($"{_name} 未查询到任何地磅物资");
                    return data;
                }

                var item = array.OrderByDescending(p => p.qpsj).FirstOrDefault();

                data = new WeighingDataCache
                {
                    //TicketCode = item.wlbh,
                    CarPlateNumber = item.carno,
                    GoodsCode = item.wlbh,
                    GoodsName = item.wlmc,
                    GoodsWeight = item.jz,
                    GoodsType = item.wlzl,
                    SendOrReceiveFlag = carInfoParams.Passageway.Direction == Core.Enums.PassagewayDirection.进 ? "收货" : "发货",
                    Sender = item.jz != 0 ? item.ylcj : string.Empty,
                    Receiver = item.jz != 0 ? string.Empty : item.ylcj,
                };
            }
            catch (Exception e)
            {
                _logger.Error($"{_name} 查询地磅物资失败:{e.Message}", e);
            }

            return data;
        }

        private async Task<ProcessResult> PostAsync(string api, JObject body)
        {
            var result = new ProcessResult();
            try
            {
                body ??= new JObject();

                var bodyStr = body.ToString(Newtonsoft.Json.Formatting.None);

                _logger.Debug($"{_name} {api} 请求参数:{bodyStr}");

                var content = new StringContent(bodyStr, Encoding.UTF8, "application/json");

                var res = await _client.PostAsync($"{_apiConfig.ApiDomain}/api/bjcjjc/ExternalService", content);

                var resStr = await res.Content.ReadAsStringAsync();

                _logger.Debug($"{_name} {api} 响应内容:{resStr}");

                var resObj = CommonUtil.TryGetJSONObject<JObject>(resStr, CommonUtil.DEFAULTJSONSERIALIZERSETTINGS) ?? new JObject
                {
                    {"code", -1},
                    {"message", "解析接口返回失败" }
                };

                if (resObj["code"].ToObject<int>() != 200)
                {
                    result.SetError(resObj["message"].ToString());
                }
                else
                {
                    result.SetSuccess(resObj);
                }

            }
            catch (Exception e)
            {
                _logger.Error($"{_name} {api} 接口失败:{e.Message}", e);
                result.SetError(e.Message);
            }

            return result;
        }
    }
}
